package net.sync.test1;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockWithConditon implements Runnable {
    /**
     * 配合关键字synchronized使用的方法如：await()、notify()、notifyAll()，同样配合ReentrantLock 使用的Conditon提供了以下方法：
     *
     * public interface Condition {
     *     void await() throws InterruptedException; // 类似于Object.wait()
     *     void awaitUninterruptibly(); // 与await()相同，但不会再等待过程中响应中断
     *     long awaitNanos(long nanosTimeout) throws InterruptedException;
     *     boolean await(long time, TimeUnit unit) throws InterruptedException;
     *     boolean awaitUntil(Date deadline) throws InterruptedException;
     *     void signal(); // 类似于Obejct.notify()
     *     void signalAll();
     * }
     *
     * ReentrantLock 实现了Lock接口，可以通过该接口提供的newCondition()方法创建Condition对象：
     *
     * public interface Lock {
     *     void lock();
     *     void lockInterruptibly() throws InterruptedException;
     *     boolean tryLock();
     *     boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
     *     void unlock();
     *     Condition newCondition();
     * }
     * ---------------------
     * 作者：Somhu
     * 来源：CSDN
     * 原文：https://blog.csdn.net/Somhu/article/details/78874634?utm_source=copy
     * 版权声明：本文为博主原创文章，转载请附上博文链接！
     */
    public static ReentrantLock lock = new ReentrantLock(true);
    public static Condition condition = lock.newCondition();

    @Override
    public void run() {
        lock.newCondition();
        try {
            lock.lock();
            System.err.println(Thread.currentThread().getName() + "-线程开始等待...");
            condition.await();
            System.err.println(Thread.currentThread().getName() + "-线程继续进行了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantLockWithConditon test = new ReentrantLockWithConditon();
        Thread t = new Thread(test, "线程ABC");
        t.start();
        Thread.sleep(1000);
        System.err.println("过了1秒后...");
        lock.lock();
        condition.signal(); // 调用该方法前需要获取到创建该对象的锁否则会产生
        // java.lang.IllegalMonitorStateException异常
        lock.unlock();
    }
}
